#include "uart_app.h"

//蓝牙变量定义
uint8_t rx_buf[2],Bluetooth_data;
uint8_t Fore,Back,Left,Right;

//串口屏测试变量
    uint8_t t;
    uint8_t len;
    uint16_t times = 0;
    int i;
// DMA接收缓冲区
uint8_t uart_rx_dma_buffer[128] = {0};
uint8_t uart_dma_buffer[128] = {0};
uint8_t uart_flag = 0;
uint16_t uart_rx_size = 0; // 记录接收到的数据长度

// 环形缓存区相关变量（仅保留接收缓存区）
//static uint8_t uart_rx_ring_pool[512] = {0}; // 接收环形缓存区内存池
//static struct rt_ringbuffer uart_rx_ringbuf; // 接收环形缓存区

//串口重定向打印函数
int my_printf(UART_HandleTypeDef *huart, const char *format, ...)
{
	char buffer[512]; // 临时存储格式化后的字符串
	va_list arg;      // 处理可变参数
	int len;          // 最终字符串长度

	va_start(arg, format);
	// 安全地格式化字符串到 buffer
	len = vsnprintf(buffer, sizeof(buffer), format, arg);
	va_end(arg);

	// 通过 HAL 库发送 buffer 中的内容
	HAL_UART_Transmit(huart, (uint8_t *)buffer, (uint16_t)len, 0xFF);
	return len;
}

/*
 * @brief UART DMA接收完成或空闲事件回调函数
 * @param huart UART句柄
 * @param Size 指示在事件发生前，DMA已经成功接收了多少字节的数据
 * @retval None
 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    // 1. 确认是目标串口 (UART5 - 蓝牙接收)
    if (huart->Instance == UART5)
    {
        extern UART_HandleTypeDef huart1;
        
        // 调试：显示DMA回调被触发
        my_printf(&huart1, "\n*** UART5 DMA CALLBACK TRIGGERED ***\n");
        my_printf(&huart1, "Received Size: %d bytes\n", Size);
        
        // 2. 紧急停止当前的 DMA 传输 (如果还在进行中)
        HAL_UART_DMAStop(huart);

        // 3. 将 DMA 缓冲区中有效的数据 (Size 个字节) 复制到待处理缓冲区
        memcpy(uart_dma_buffer, uart_rx_dma_buffer, Size); 
        
        // 调试：显示原始接收数据
        my_printf(&huart1, "Raw DMA data: ");
        for(int i = 0; i < Size && i < 20; i++) {
            my_printf(&huart1, "%02X ", uart_rx_dma_buffer[i]);
        }
        my_printf(&huart1, "\n");
        
        // 4. 举起"到货通知旗"，告诉主循环有数据待处理
        uart_flag = 1;
        my_printf(&huart1, "uart_flag set to 1\n");

        // 5. 清空 DMA 接收缓冲区，为下次接收做准备
        memset(uart_rx_dma_buffer, 0, sizeof(uart_rx_dma_buffer));

        // 6. **关键：重新启动下一次 DMA 空闲接收**
        extern UART_HandleTypeDef huart5;
        HAL_StatusTypeDef restart_status = HAL_UARTEx_ReceiveToIdle_DMA(&huart5, uart_rx_dma_buffer, sizeof(uart_rx_dma_buffer));
        my_printf(&huart1, "DMA restart status: %d\n", restart_status);
        
        my_printf(&huart1, "*** DMA CALLBACK COMPLETE ***\n\n");
    }
    else {
        // 调试：如果不是UART5，显示是哪个串口
        extern UART_HandleTypeDef huart1;
        my_printf(&huart1, "DMA callback from other UART: %p\n", huart->Instance);
    }
}
/**
 * @brief  处理 DMA 接收到的 UART 数据
 * @param  None
 * @retval None
 */
void uart_proc(void)
{
	// 1. 检查"到货通知旗"
    if(uart_flag == 0) 
        return; // 旗子没举起来，说明没新货，直接返回
    
    // 2. 放下旗子，表示我们已经注意到新货了
    //    防止重复处理同一批数据
    uart_flag = 0;
	
    // 3. 处理蓝牙遥控指令
    char *cmd = (char*)uart_dma_buffer;
    
    // 调试：显示接收到的原始数据
    my_printf(&huart1, "\n=== UART5 DATA RECEIVED ===\n");
    my_printf(&huart1, "Raw data: [%s]\n", cmd);
    my_printf(&huart1, "Length: %d\n", strlen(cmd));
    my_printf(&huart1, "Hex: ");
    for(int i = 0; i < strlen(cmd) && i < 10; i++) {
        my_printf(&huart1, "%02X ", (uint8_t)cmd[i]);
    }
    my_printf(&huart1, "\n");
    
    // 前进指令
    if(strncmp(cmd, "forward", 7) == 0 || strncmp(cmd, "F", 1) == 0) {
        Fore = 1;
        Back = Left = Right = 0;  // 清除其他指令
        my_printf(&huart1, "*** FORWARD COMMAND RECEIVED ***\n");
        my_printf(&huart1, "Fore=%d, Back=%d, Left=%d, Right=%d\n", Fore, Back, Left, Right);
    }
    // 后退指令
    else if(strncmp(cmd, "backward", 8) == 0 || strncmp(cmd, "B", 1) == 0) {
        Back = 1;
        Fore = 0;
        my_printf(&huart1, "Backward\n");
    }
    // 左转指令
    else if(strncmp(cmd, "left", 4) == 0 || strncmp(cmd, "L", 1) == 0) {
        Left = 1;
        Right = 0;
        my_printf(&huart1, "Left\n");
    }
    // 右转指令
    else if(strncmp(cmd, "right", 5) == 0 || strncmp(cmd, "R", 1) == 0) {
        Right = 1;
        Left = 0;
        my_printf(&huart1, "Right\n");
    }
    // 停止指令
    else if(strncmp(cmd, "stop", 4) == 0 || strncmp(cmd, "S", 1) == 0) {
        Fore = Back = Left = Right = 0;
        my_printf(&huart1, "*** STOP COMMAND RECEIVED ***\n");
        my_printf(&huart1, "Fore=%d, Back=%d, Left=%d, Right=%d\n", Fore, Back, Left, Right);
    }
    // 兼容原有的b0down指令
    else if(strncmp(cmd, "b0down", 6) == 0) {
        my_printf(&huart1, "OK\n");
    }
    // 数字指令解析（如：1234，前两位控制前后，后两位控制左右）
    else if(strlen(cmd) >= 4 && cmd[0] >= '0' && cmd[0] <= '9') {
        // 解析4位数字指令
        int front_back = (cmd[0] - '0') * 10 + (cmd[1] - '0');
        int left_right = (cmd[2] - '0') * 10 + (cmd[3] - '0');
        
        // 前后控制（50为中位，大于50前进，小于50后退）
        if(front_back > 55) {
            Fore = 1; Back = 0;
        } else if(front_back < 45) {
            Back = 1; Fore = 0;
        } else {
            Fore = Back = 0;
        }
        
        // 左右控制（50为中位，大于50右转，小于50左转）
        if(left_right > 55) {
            Right = 1; Left = 0;
        } else if(left_right < 45) {
            Left = 1; Right = 0;
        } else {
            Left = Right = 0;
        }
        
        my_printf(&huart1, "CMD: %d,%d\n", front_back, left_right);
    }
    // 速度档位控制指令
    else if(strncmp(cmd, "speed1", 6) == 0) {
        Set_Speed_Level(1);
        my_printf(&huart1, "*** SPEED 1 (SLOW) ACTIVATED ***\n");
    }
    else if(strncmp(cmd, "speed2", 6) == 0) {
        Set_Speed_Level(2);
        my_printf(&huart1, "*** SPEED 2 (MEDIUM) ACTIVATED ***\n");
    }
    else if(strncmp(cmd, "speed3", 6) == 0) {
        Set_Speed_Level(3);
        my_printf(&huart1, "*** SPEED 3 (FAST) ACTIVATED ***\n");
    }
    // 查询当前速度档位
    else if(strncmp(cmd, "speed?", 6) == 0) {
        uint8_t current_level = Get_Speed_Level();
        const char* speed_desc[] = {"", "SLOW", "MEDIUM", "FAST"};
        my_printf(&huart1, "Current Speed Level: %d (%s)\n", current_level, speed_desc[current_level]);
    }
    // PWM测试指令
    else if(strncmp(cmd, "pwm", 3) == 0) {
        my_printf(&huart1, "=== PWM Test Mode ===\n");
        my_printf(&huart1, "Current PWM: M1=%d, M2=%d\n", g_motor1_pwm, g_motor2_pwm);
        my_printf(&huart1, "Use F/L/R/S to test different PWM values\n");
        my_printf(&huart1, "==================\n");
    }
    // 系统状态查询指令
    else if(strncmp(cmd, "status", 6) == 0) {
        my_printf(&huart1, "=== System Status ===\n");
        my_printf(&huart1, "System Enable: %s\n", g_system_enable ? "ON" : "OFF");
        my_printf(&huart1, "Encoders: L=%d, R=%d\n", g_encoder_left, g_encoder_right);
        my_printf(&huart1, "Motors: M1=%d, M2=%d\n", g_motor1_pwm, g_motor2_pwm);
        my_printf(&huart1, "Controls: F=%d,B=%d,L=%d,R=%d\n", Fore, Back, Left, Right);
        my_printf(&huart1, "Speed Level: %d\n", Get_Speed_Level());
        my_printf(&huart1, "Control Mode: Direct PWM\n");
        my_printf(&huart1, "Time: %lu ms\n", HAL_GetTick());
        my_printf(&huart1, "====================\n");
    }
    // 编码器测试指令
    else if(strncmp(cmd, "encoder", 7) == 0) {
        my_printf(&huart1, "=== Encoder Test ===\n");
        my_printf(&huart1, "Raw Values: L=%d, R=%d (per 10ms)\n", g_encoder_left, g_encoder_right);
        my_printf(&huart1, "Speed Values: L=%.0f, R=%.0f (pulses/sec)\n", 
                 (float)g_encoder_left * 100.0f, (float)g_encoder_right * 100.0f);
        my_printf(&huart1, "Try manually rotating wheels to test encoders\n");
        my_printf(&huart1, "===================\n");
    }
    // 手动测试指令
    else if(strncmp(cmd, "testF", 5) == 0) {
        Fore = 1;
        Back = Left = Right = 0;
        my_printf(&huart1, "*** MANUAL TEST: Fore=1 ***\n");
    }
    else if(strncmp(cmd, "testS", 5) == 0) {
        Fore = Back = Left = Right = 0;
        my_printf(&huart1, "*** MANUAL TEST: All=0 ***\n");
    }
    // 直接电机测试指令
    else if(strncmp(cmd, "test60", 6) == 0) {
        Test_Motors_Direct(60, 90);
        my_printf(&huart1, "*** DIRECT TEST: M1=60, M2=90 ***\n");
    }
    else if(strncmp(cmd, "test80", 6) == 0) {
        Test_Motors_Direct(80, 100);
        my_printf(&huart1, "*** DIRECT TEST: M1=80, M2=100 ***\n");
    }
    else if(strncmp(cmd, "test0", 5) == 0) {
        Test_Motors_Direct(0, 0);
        my_printf(&huart1, "*** DIRECT TEST: M1=0, M2=0 (STOP) ***\n");
    }
    // 后退测试指令
    else if(strncmp(cmd, "testB", 5) == 0) {
        Test_Backward();
        my_printf(&huart1, "*** BACKWARD TEST ACTIVATED ***\n");
    }
    else if(strncmp(cmd, "testBack", 8) == 0) {
        Test_Motors_Direct(-60, -90);
        my_printf(&huart1, "*** DIRECT BACKWARD TEST: M1=-60, M2=-90 ***\n");
    }
    // 右转测试指令
    else if(strncmp(cmd, "testR", 5) == 0) {
        Right = 1;
        Fore = Back = Left = 0;
        my_printf(&huart1, "*** RIGHT TURN TEST: Right=1 ***\n");
    }
    else {
        // 显示接收到的其他数据（用于调试）
        my_printf(&huart1, "Unknown command: [%s]\n", uart_dma_buffer);
        my_printf(&huart1, "Available commands:\n");
        my_printf(&huart1, "Movement: F, L, R, S\n");
        my_printf(&huart1, "Speed: speed1, speed2, speed3, speed?\n");
        my_printf(&huart1, "Debug: status, encoder, pwm\n");
    }
   
    // 4. 清空"待处理货架"，为下次接收做准备
    memset(uart_dma_buffer, 0, sizeof(uart_dma_buffer));
}
